package client

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"gin-epg/internal/app/dao"
	"gin-epg/internal/app/entity"
	"github.com/go-resty/resty/v2"
	"time"
)

// HandleTplCron 处理 TPL 节目单
func HandleTplCron(beforeDay, afterDay int) error {
	dao.Logger.Infof("handleTplCron start")
	source := "tpl"

	client := resty.New()
	db := dao.SqlSession

	for dayOffset := -beforeDay; dayOffset <= afterDay; dayOffset++ {
		urlDate := time.Now().AddDate(0, 0, dayOffset).Format("2006-01-02")
		dao.Logger.Infof("Processing date: %s", urlDate)

		// 查询假日/工作日 来自github项目 https://github.com/Dreace/ChinaHolidayAPI
		isWorkDay := true
		holidayURL := fmt.Sprintf("https://holiday.dreace.top/?date=%s", urlDate)
		resp, err := client.R().Get(holidayURL)
		if err != nil {
			return fmt.Errorf("failed to fetch holiday data for date %s: %v", urlDate, err)
		}

		var holidayData map[string]interface{}
		if err := json.Unmarshal(resp.Body(), &holidayData); err != nil {
			return fmt.Errorf("failed to unmarshal holiday data for date %s: %v", urlDate, err)
		}

		if holidayData["type"].(string) == "工作日" {
			isWorkDay = true
		} else {
			isWorkDay = false
		}
		dao.Logger.Infof("Final isWorkDay for date %s: %v", urlDate, isWorkDay)

		// 查询模板主表 epg_program_tpl
		var templates []entity.EpgProgramTpl
		if err := db.Find(&templates).Error; err != nil {
			return fmt.Errorf("failed to query epg_program_tpl: %v", err)
		}

		dao.Logger.Infof("handleTplCron templates: %v", templates)
		if len(templates) > 0 {
			for _, template := range templates {
				channel := template.Channel
				mode := template.Mode
				id := template.Id
				var dayType string

				if mode == "5+2" {
					// 判断今天是否是星期一~星期五
					if time.Now().AddDate(0, 0, dayOffset).Weekday() >= time.Monday && time.Now().AddDate(0, 0, dayOffset).Weekday() <= time.Friday {
						dayType = "5"
					} else {
						dayType = "2"
					}
				} else if mode == "work+rest" {
					// 判断今天是否是工作日或者假日
					if isWorkDay {
						dayType = "work"
					} else {
						dayType = "rest"
					}
				}
				dao.Logger.Infof("handleTplCron dayType for date %s: %s", urlDate, dayType)

				// 查询模板子表 epg_program_tpl_seg
				var segments []entity.EpgProgramTplSeg
				if err := db.Where("tpl_id = ? AND day_type = ?", id, dayType).Find(&segments).Error; err != nil {
					return fmt.Errorf("failed to query epg_program_tpl_seg for date %s: %v", urlDate, err)
				}

				dateParsed, _ := time.Parse("2006-01-02", urlDate)

				// 获取当前日期范围内的已有节目记录
				var existingRecords []entity.EpgProgramCollect
				if err := db.Where(&entity.EpgProgramCollect{Channel: channel, Date: entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}}, Source: source}).Find(&existingRecords).Error; err != nil {
					dao.Logger.Errorf("failed to get existing records for date %s: %v", urlDate, err)
					continue
				}

				existingMap := make(map[string]*entity.EpgProgramCollect)
				for i := range existingRecords {
					existingMap[existingRecords[i].Start] = &existingRecords[i]
				}

				var newPrograms, updatePrograms, deletePrograms []entity.EpgProgramCollect

				for _, segment := range segments {
					startTime := segment.StartTime
					endTime := segment.EndTime
					name := segment.Name
					desc := segment.Desc

					if channel != "" && urlDate != "" && startTime != "" && endTime != "" {
						if existingRecord, ok := existingMap[startTime]; ok {
							if existingRecord.Title != name || existingRecord.End != endTime {
								existingRecord.Title = name
								existingRecord.Desc = desc
								existingRecord.End = endTime
								existingRecord.UpdateTime = entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}}
								updatePrograms = append(updatePrograms, *existingRecord)
							}
							delete(existingMap, startTime)
						} else {
							newRecord := entity.EpgProgramCollect{
								Title:      name,
								Desc:       desc,
								Source:     source,
								Channel:    channel,
								Date:       entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}},
								Start:      startTime,
								End:        endTime,
								CreateTime: entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}},
							}
							newPrograms = append(newPrograms, newRecord)
						}
					}
				}

				// 处理需要删除的记录
				for _, record := range existingMap {
					deletePrograms = append(deletePrograms, *record)
				}

				// 执行数据库操作
				if len(updatePrograms) > 0 {
					for _, program := range updatePrograms {
						if err := db.Model(&program).Updates(entity.EpgProgramCollect{Title: program.Title, Desc: program.Desc, End: program.End, UpdateTime: program.UpdateTime}).Error; err != nil {
							dao.Logger.Errorf("update error for date %s: %v", urlDate, err)
						} else {
							dao.Logger.Debugf("update success for date %s: %v", urlDate, program)
						}
					}
				}

				if len(newPrograms) > 0 {
					for _, program := range newPrograms {
						if err := db.Create(&program).Error; err != nil {
							dao.Logger.Errorf("insert error for date %s: %v", urlDate, err)
						} else {
							dao.Logger.Debugf("insert success for date %s: %v", urlDate, program)
						}
					}
				}

				if len(deletePrograms) > 0 {
					for _, program := range deletePrograms {
						if err := db.Delete(&program).Error; err != nil {
							dao.Logger.Errorf("delete error for date %s: %v", urlDate, err)
						} else {
							dao.Logger.Debugf("delete success for date %s: %v", urlDate, program)
						}
					}
				}
			}
		}
	}
	return nil
}
